#coding:utf-8

import wx	

#SandBoxObject e ToolBoxObject são as classes gerais

class SandBoxObject(wx.Panel):
	'''Objeto criado no target. Classe padrão dos objetos que serão jogados
	Target
	'''
	
	ST_NORMAL = 1
	
	ST_SIZE_NS = 2
	ST_SIZE_WE = 4
	ST_SIZE_NW = 8
	ST_SIZE_NE = 16
	ST_SIZE_SE = 32
	ST_SIZE_SW = 64
	
	ST_HOLD_LEFT = 128
	ST_OTHER_DIR = 256
	
	def setState(self,s):
		if s == 0:
			self._state = 0
		else:
			self._state |= s
	
	def resetState(self,s):
		self._state &= (~s)
			
	def checkState(self,state):
		if (self._state | state) == self._state:
			return True
		
		return False	
	
	def getPosRelClick(self):
		pos_rel = ( self._absPos[0] - self._clickPos[0], self._absPos[1] - self._clickPos[1] )
		
		self._clickPos[0] += pos_rel[0]
		self._clickPos[1] += pos_rel[1]	
		
		return pos_rel
	
	def __init__(self,parent,pos):
		wx.Panel.__init__(self,parent,-1,size=(40,40),pos=pos)				
				
		self.Bind(wx.EVT_PAINT,self.paint)				
				
		self.Bind(wx.EVT_LEFT_DOWN,self.__OnLeftDown__)
		self.Bind(wx.EVT_LEFT_UP,self.__OnLeftUp__)				
		self.Bind(wx.EVT_MOTION,self.__OnMotion__)

		self._relPos = (0,0)	#Dentro do Window
		self._absPos = (0,0)	#Dentro do Parent
		self._clickPos = (0,0)	#Clique dentro do Window
		self._state = 0
		
	def __OnLeftUp__(self,evt):
		self.resetState( SandBoxObject.ST_HOLD_LEFT )		
		
	def __OnLeftDown__(self,evt):
		self._clickPos = [ self.GetPosition().x + evt.GetPosition().x, self.GetPosition().y + evt.GetPosition().y ]
		self.setState( SandBoxObject.ST_HOLD_LEFT )
		
		
	def __OnMotion__(self,evt):
		self._absPos = self.GetPosition() + evt.GetPosition()
		pos = evt.GetPosition()
		size = self.GetSize()
		
		if not ( self.checkState( SandBoxObject.ST_HOLD_LEFT ) ):
		
			if pos.x >=0 and pos.x <=5 and pos.y>=0 and pos.y<=2:
				self.resetState( SandBoxObject.ST_SIZE_NS | SandBoxObject.ST_SIZE_WE |SandBoxObject.ST_SIZE_NW |SandBoxObject.ST_SIZE_NE |SandBoxObject.ST_SIZE_SE |SandBoxObject.ST_SIZE_SW| SandBoxObject.ST_OTHER_DIR)	
				self.setState(SandBoxObject.ST_SIZE_NW)
			
			elif pos.x >=size.x-5 and pos.x <=size.x and pos.y>=0 and pos.y<=2:
				self.resetState( SandBoxObject.ST_SIZE_NS | SandBoxObject.ST_SIZE_WE |SandBoxObject.ST_SIZE_NW |SandBoxObject.ST_SIZE_NE |SandBoxObject.ST_SIZE_SE |SandBoxObject.ST_SIZE_SW| SandBoxObject.ST_OTHER_DIR)	
				self.setState(SandBoxObject.ST_SIZE_NE)

			elif pos.x >=0 and pos.x <=5 and pos.y>=size.y-2 and pos.y<=size.y:
				self.resetState( SandBoxObject.ST_SIZE_NS | SandBoxObject.ST_SIZE_WE |SandBoxObject.ST_SIZE_NW |SandBoxObject.ST_SIZE_NE |SandBoxObject.ST_SIZE_SE |SandBoxObject.ST_SIZE_SW| SandBoxObject.ST_OTHER_DIR)	
				self.setState(SandBoxObject.ST_SIZE_SW)
				
			elif pos.x >=size.x-5 and pos.x <=size.x and pos.y>size.y-2 and pos.y<=size.y:			
				self.resetState( SandBoxObject.ST_SIZE_NS | SandBoxObject.ST_SIZE_WE |SandBoxObject.ST_SIZE_NW |SandBoxObject.ST_SIZE_NE |SandBoxObject.ST_SIZE_SE |SandBoxObject.ST_SIZE_SW| SandBoxObject.ST_OTHER_DIR)	
				self.setState(SandBoxObject.ST_SIZE_SE)
				
			elif (pos.y>=0 and pos.y<=2):
				self.resetState( SandBoxObject.ST_SIZE_NS | SandBoxObject.ST_SIZE_WE |SandBoxObject.ST_SIZE_NW |SandBoxObject.ST_SIZE_NE |SandBoxObject.ST_SIZE_SE |SandBoxObject.ST_SIZE_SW | SandBoxObject.ST_OTHER_DIR)	
				self.setState(SandBoxObject.ST_SIZE_NS)
				self.setState(SandBoxObject.ST_OTHER_DIR)
				
			elif (pos.y>=size.y-2 and pos.y<=size.y):
				self.resetState( SandBoxObject.ST_SIZE_NS | SandBoxObject.ST_SIZE_WE |SandBoxObject.ST_SIZE_NW |SandBoxObject.ST_SIZE_NE |SandBoxObject.ST_SIZE_SE |SandBoxObject.ST_SIZE_SW | SandBoxObject.ST_OTHER_DIR)	
				self.setState(SandBoxObject.ST_SIZE_NS)				
								
			elif (pos.x >=0 and pos.x <=5):				
				self.resetState( SandBoxObject.ST_SIZE_NS | SandBoxObject.ST_SIZE_WE |SandBoxObject.ST_SIZE_NW |SandBoxObject.ST_SIZE_NE |SandBoxObject.ST_SIZE_SE |SandBoxObject.ST_SIZE_SW| SandBoxObject.ST_OTHER_DIR)	
				self.setState(SandBoxObject.ST_SIZE_WE)
				self.setState(SandBoxObject.ST_OTHER_DIR)
								
			elif (pos.x >=size.x-5 and pos.x <=size.x):
				self.resetState( SandBoxObject.ST_SIZE_NS | SandBoxObject.ST_SIZE_WE |SandBoxObject.ST_SIZE_NW |SandBoxObject.ST_SIZE_NE |SandBoxObject.ST_SIZE_SE |SandBoxObject.ST_SIZE_SW| SandBoxObject.ST_OTHER_DIR)	
				self.setState(SandBoxObject.ST_SIZE_WE)				
												
			else:
				self.resetState( SandBoxObject.ST_SIZE_NS | SandBoxObject.ST_SIZE_WE |SandBoxObject.ST_SIZE_NW |SandBoxObject.ST_SIZE_NE |SandBoxObject.ST_SIZE_SE |SandBoxObject.ST_SIZE_SW| SandBoxObject.ST_OTHER_DIR)		
				self.setState(SandBoxObject.ST_NORMAL)
				
		
		
		self.doAction(self._absPos)	
			

	def doAction(self,pos):
		
		if self.checkState(SandBoxObject.ST_SIZE_WE):				
			self.SetCursor( wx.StockCursor(wx.CURSOR_SIZEWE) )
			
			if self.checkState(SandBoxObject.ST_HOLD_LEFT): 
				self.OnResize(self._state,pos)		
	
		elif self.checkState(SandBoxObject.ST_SIZE_NS):				
			self.SetCursor( wx.StockCursor(wx.CURSOR_SIZENS) )		
			
			if self.checkState(SandBoxObject.ST_HOLD_LEFT): 
				self.OnResize(self._state,pos)		
					
		elif self.checkState(SandBoxObject.ST_SIZE_NW):		
			self.SetCursor( wx.StockCursor(wx.CURSOR_SIZENWSE) )
			
			if self.checkState(SandBoxObject.ST_HOLD_LEFT): 
				self.OnResize(self._state,pos)		
			
		elif self.checkState(SandBoxObject.ST_SIZE_NE):
			self.SetCursor( wx.StockCursor(wx.CURSOR_SIZENESW) )
			
			if self.checkState(SandBoxObject.ST_HOLD_LEFT): 
				self.OnResize(self._state,pos)		
			
		elif self.checkState(SandBoxObject.ST_SIZE_SW):
			self.SetCursor( wx.StockCursor(wx.CURSOR_SIZENESW) )
			
			if self.checkState(SandBoxObject.ST_HOLD_LEFT): 
				self.OnResize(self._state,pos)		
			
		elif self.checkState(SandBoxObject.ST_SIZE_SE):
			self.SetCursor( wx.StockCursor(wx.CURSOR_SIZENWSE) )	
			
			if self.checkState(SandBoxObject.ST_HOLD_LEFT): 
				self.OnResize(self._state,pos)		
			
		elif self.checkState(SandBoxObject.ST_NORMAL):
			self.SetCursor( wx.StockCursor(wx.CURSOR_SIZING) )	
			
			if self.checkState(SandBoxObject.ST_HOLD_LEFT): 
				self.OnMotion(pos)

	def paint(self,pos):
		pass
		

class ToolBoxObject():
	'''Objeto representativo do que sera posto no target.
		sbo = Instancia de uma classe SandBoxObject. Este objeto é o que
		será renderizado no painel de Target.
	'''
	
	def __init__(self,object):
		self.sbo = object.sbo
		
	def create(self,container,pos):
		return self.sbo(container,pos)


#Abaixo são as classes específicas

class RectSurfacePotentialSBO(SandBoxObject):
	'''
		Aqui é definido o comportamento visual do objeto,  dentro do 
		sandbox
	'''
	def __init__(self,parent,pos):
		SandBoxObject.__init__(self,parent,pos)
		
		self.p1 = [0,0]
		self.p2 = [self.GetSize().x,0]
		self.p3 = [self.GetSize().x,self.GetSize().y]
		self.p4 = [0,self.GetSize().y]
		
		self.SetBackgroundColour("white")
	
	def paintContext(self,dc):
		dc.SetBackground( wx.Brush( "white" ) )
		dc.Clear()
		
		dc.SetPen(wx.Pen("dark red", 4))
		
		dc.DrawLine(self.p1[0],self.p1[1], self.p2[0],self.p2[1])
		dc.DrawLine(self.p2[0],self.p2[1], self.p3[0],self.p3[1])
		dc.DrawLine(self.p3[0],self.p3[1], self.p4[0],self.p4[1])
		dc.DrawLine(self.p4[0],self.p4[1], self.p1[0],self.p1[1])
			
	def paint(self,pos):
		dc = wx.PaintDC(self)		
		self.paintContext(dc)
		
	
	def OnMotion(self,pos):
		new_pos = self.getPosRelClick()				
		self.SetPosition( ( self.GetPosition().x+new_pos[0],self.GetPosition().y+new_pos[1]) )
		
	def OnResize(self,state,pos):				
		pos_rel = self.getPosRelClick()
		
		new_pos_xy = ( self.GetPosition().x + pos_rel[0], self.GetPosition().y + pos_rel[1] )				
		new_pos_y = ( self.GetPosition().x , self.GetPosition().y + pos_rel[1] )		
		new_pos_x = ( self.GetPosition().x + pos_rel[0] , self.GetPosition().y )		
		
		if self.checkState(SandBoxObject.ST_SIZE_WE):						
			
			if self.checkState(SandBoxObject.ST_OTHER_DIR):
				self.p2[0] -= pos_rel[0]
				self.p3[0] -= pos_rel[0]		
			
				self.SetPosition( new_pos_x )		
			else:
				self.p2[0] += pos_rel[0]
				self.p3[0] += pos_rel[0]		
				
				
		if self.checkState(SandBoxObject.ST_SIZE_NS):
			
			if self.checkState(SandBoxObject.ST_OTHER_DIR):
				self.p4[1] -= pos_rel[1]
				self.p3[1] -= pos_rel[1]
				
				self.SetPosition( new_pos_xy )		
			else:
				self.p4[1] += pos_rel[1]
				self.p3[1] += pos_rel[1]
			
		if self.checkState(SandBoxObject.ST_SIZE_NE):			
			self.p3[0] += pos_rel[0]		
			self.p2[0] += pos_rel[0]
			
			self.p3[1] -= pos_rel[1]
			self.p4[1] -= pos_rel[1]
			
			self.SetPosition( new_pos_y )

			
		if self.checkState(SandBoxObject.ST_SIZE_SE):
			self.p4[1] += pos_rel[1]
			self.p2[0] += pos_rel[0]
			
			self.p3[0] += pos_rel[0]
			self.p3[1] += pos_rel[1]
			
		
		if self.checkState(SandBoxObject.ST_SIZE_SW):
			self.p3[1] += pos_rel[1]			
			self.p4[1] += pos_rel[1]
			
			self.p3[0] -= pos_rel[0]
			self.p2[0] -= pos_rel[0]
						
			self.SetPosition( new_pos_x )
			
		if self.checkState(SandBoxObject.ST_SIZE_NW):			
			self.p3[0] -= pos_rel[0]
			self.p2[0] -= pos_rel[0]
			
			self.p3[1] -= pos_rel[1]
			self.p4[1] -= pos_rel[1]
						
			self.SetPosition( new_pos_xy )			
						
		self.SetSize( (self.p2[0] - self.p1[0], self.p4[1] - self.p1[1]) )
			
		dc = wx.ClientDC(self)
		self.paintContext(dc)		
				
				
class RectSurfacePotential():
	
	def __init__(self):
		self.sbo = RectSurfacePotentialSBO
		self.v0 = 10
			